package com.czp.opensource.profiler.cfg;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;

import com.czp.opensource.profiler.ClassAgent;
import com.czp.opensource.profiler.filter.ClassNameFilter;
import com.czp.opensource.profiler.filter.InjectionFilter;
import com.czp.opensource.profiler.log.LogWrapper;

/**
 * 
 * @description
 *       <p>this file is TODO</p>
 * @author 
 *        Czp
 * @version 
 *        1.0(2014-5-10)
 *
 */
public class Configuration {


	public static final String FILTERS = "Filters";
	
	public static final String CONFIG_FLAGS = "config_";
	
	private static final String CONFIG_FILE_PATH = "config";
	
	public static final String IS_DEBUG_ENABLE = "debug_enable";
	
	public static Map<String,Object> beanFactory = new HashMap<String, Object>();
	
	
	@SuppressWarnings("unchecked")
	public static List<InjectionFilter> loadFilter() {
	    initConfig();
		return (List<InjectionFilter>) beanFactory.get(FILTERS);
	}

	
	/**
	 * 
	 * @desc:
	 *     <p>加载配置文件</p>
	 */
	private static void initConfig() {
		if(beanFactory.isEmpty())
		{
			synchronized (beanFactory) {
				String cfgFile = System.getProperty(CONFIG_FILE_PATH);
				if(cfgFile!=null)
				{
					try {
						Reader inStream = new FileReader(cfgFile);
						Properties properties = new Properties();
						properties.load(inStream );
						parseConfigFile(properties);
					} catch (FileNotFoundException e) {
						LogWrapper.getInstance().info("config file is not find: "+e.toString());
					} catch (Exception e) {
						LogWrapper.getInstance().info("Read config file error:"+e.toString());
					}
				}
			}
		}
		
	}


	/**
	 * 
	 * @desc:
	 *     <p>解析配置文件</p> 
	 * @param properties
	 * @return 
	 */
	private static void parseConfigFile(Properties properties) {
		
		List<InjectionFilter> filters = new ArrayList<InjectionFilter>();
		Set<Entry<Object, Object>> objs =  properties.entrySet();
		for (Entry<Object, Object> entry : objs) {
			String key = entry.getKey().toString();
			String value = entry.getValue().toString();
			//add the config line
			if(key.startsWith(CONFIG_FLAGS))
			{
				key = key.substring(key.indexOf(CONFIG_FLAGS)+CONFIG_FLAGS.length());
				beanFactory.put(key, value);
				continue;
			}	
			ClassNameFilter filter = converConfigToFilterObj(key,value);
			filters.add(filter);
		}
        beanFactory.put(FILTERS, filters);		
	}


	/**
	 * 
	 * @desc:
	 *     <p>将配置转换为filter对象</p> 
	 * @param key
	 * @param string
	 * @return
	 */
	private static ClassNameFilter converConfigToFilterObj(String className,
			String methods) {
		
		ClassNameFilter filter = new ClassNameFilter();
		List<String> methds = Arrays.asList(methods.split(","));
		ClassAgent agent = new ClassAgent(className, methds);
		Map<String, ClassAgent> fileterClass = new HashMap<String, ClassAgent>();
		fileterClass.put(agent.getTargetClass(), agent);
		filter.setFileterClass(fileterClass );
		
		return filter;
	}


	public static boolean isDebug(String beanId) {
		Object bean = beanFactory.get(beanId);
		String beanStr = bean==null?"false":bean.toString();
		return Boolean.valueOf(beanStr);
	}

	public static void clear(){
		beanFactory.clear();
	}


	/**
	 * 
	 * @desc:
	 *     <p>从bean工厂获取bean</p> 
	 * @param beanId
	 * @return
	 */
	public static  Object getBean(String beanId) {
		return beanFactory.get(beanId);
	}
}
